/******************************************************************************* 
 * Copyright (C) 2012-2015 Microfountain Technology, Inc. All Rights Reserved. 
 * 
 * Unauthorized copying of this file, via any medium is strictly prohibited.   
 * Proprietary and confidential
 * 
 * Last Modified: 2015-9-18 15:14:06
 ******************************************************************************/
package cn.cmcc.online.smsapi.sdk.util;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

import javax.xml.parsers.DocumentBuilderFactory;

import org.json.JSONArray;
import org.json.JSONException;
import org.w3c.dom.Document;

import cn.cmcc.online.smsapi.sdk.constant.Constant;
import cn.cmcc.online.smsapi.sdk.log.LogManager;

public class StringUtils {

    private static final String hexString = "0123456789ABCDEF";
    private static final String CHARSETNAME = "UTF-8";

    public static final String MPLUG86 = "+86";

    private static final String phoneFiled86 = "+86";

    private static final String phoneFiled = "\\+86";
    private static final String phoneFont0086 = "0086";
    private static final String phoneFont86 = "86";

    private static final String phoneFiled17951 = "17951";

    private static final String phoneFiled12593 = "12593";

    public static final String phoneFiled12520 = "12520";

    public static final String phoneFiled17911 = "17911";

    public static final String phoneFiled179110 = "179110";

    public static final String phoneFiled10193 = "10193";

    public static final String phoneFiled17909 = "17909";

    public static final String phoneFiled17908 = "17908";

    public static String getSubString(String org) {
        if (!isNull(org) && org.length() >= 7) {
            return org.substring(0, 7);
        }
        return org;
    }

    /**
     * 去掉手机号前面的+86
     * 
     * @param phoneNumber
     * @return
     */
    public static String getPhoneNumberNo86(String phoneNumber) {
        if (!StringUtils.isNull(phoneNumber)) {
            phoneNumber = phoneNumber.replace(" ", "").replace("-", "")
                    .replace("(", "").replace(")", "");
            if (phoneNumber.startsWith(phoneFiled86)) {
                phoneNumber = phoneNumber.replaceFirst(phoneFiled, "");
            } else if (phoneNumber.startsWith(phoneFont0086)) {
                phoneNumber = phoneNumber.replaceFirst(phoneFont0086, "");
            } else if (phoneNumber.startsWith(phoneFont86)) {
                phoneNumber = phoneNumber.replaceFirst(phoneFont86, "");
            } else if (phoneNumber.startsWith(phoneFiled17951)
                    && phoneNumber.length() > 10) {
                phoneNumber = phoneNumber.replaceFirst(phoneFiled17951, "");
            } else if (phoneNumber.startsWith(phoneFiled12593)
                    && phoneNumber.length() > 10) {
                phoneNumber = phoneNumber.replaceFirst(phoneFiled12593, "");
            } else if (phoneNumber.startsWith(phoneFiled12520)
                    && phoneNumber.length() > 10) {
                phoneNumber = phoneNumber.replaceFirst(phoneFiled12520, "");
            }

        }
        return phoneNumber;
    }

    public static boolean isPhoneNumber(String phoneNumber) {
        if (isNull(phoneNumber))
            return false;
        phoneNumber = getPhoneNumberNo86(phoneNumber);
        return sj(phoneNumber);

    }

    public static boolean sj(String pn) {

        if (pn != null && pn.length() == 11) {
            if ("13800138000".equals(pn)) {
                return false;
            }
            if (pn.startsWith("13") || pn.startsWith("14")
                    || pn.startsWith("15") || pn.startsWith("18")
                    /*SDK-544 zhaojiangwei 20160719 start */
                    || pn.startsWith("17")) {
            		/*SDK-544 zhaojiangwei 20160719 end */
                return true;
            }
        }
        return false;
    }

    public static boolean isNumber(String phoneNumber) {

        boolean isTrue = false;
        if (!StringUtils.isNull(phoneNumber)) {
            phoneNumber = getPhoneNumberNo86(phoneNumber);
            Pattern pattern = Pattern.compile("[0-9]*");
            Matcher isNum = pattern.matcher(phoneNumber);
            if (!isNum.matches()) {
                return false;
            }
            return true;
        }
        return isTrue;

    }

    public static boolean isNull(String str) {
        if (str == null || str.trim().length() == 0
                || str.trim().equalsIgnoreCase("null")) {
            return true;
        }

        return false;
    }

    public static boolean isNull2(String str) {
        if (str == null || str.trim().length() == 0) {
            return true;
        }

        return false;
    }

    /**
     * gZip解压方法
     * 
     * @throws Throwable
     */
    public static byte[] uncompressGZip(byte[] data) throws Exception {
        byte[] b = null;
        ByteArrayInputStream bis = new ByteArrayInputStream(data);
        GZIPInputStream gzip = new GZIPInputStream(bis);
        byte[] buf = new byte[1024];
        int num = -1;
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        while ((num = gzip.read(buf, 0, buf.length)) != -1) {
            baos.write(buf, 0, num);
        }
        b = baos.toByteArray();
        baos.flush();
        baos.close();
        gzip.close();
        bis.close();
        return b;
    }

    /***
     * 压缩GZip
     * 
     * @param data
     * @return
     */
    public static byte[] compressGZip(byte[] data) {
        byte[] b = null;
        try {
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            GZIPOutputStream gzip = new GZIPOutputStream(bos);
            gzip.write(data);
            gzip.finish();
            gzip.close();
            b = bos.toByteArray();
            bos.close();
        } catch (Throwable e) {
//            ex.printStackTrace();
            LogManager.e(Constant.TAG, "compressGZip: ", e);

        }
        return b;
    }
	/* SDK-493 hewngao 20160618 start */
    public static String encode(String str) {
    	try{
    		byte[]   bytes = str.getBytes(CHARSETNAME);
    		return encode(bytes);
    	}catch(Throwable e){
    	    LogManager.e(Constant.TAG, "encode: ", e);
    	}
    	return null;
    }
    
    public static String encode(byte[] bytes){
    	 try {
             StringBuilder sb = new StringBuilder(bytes.length * 2);
             for (int i = 0; i < bytes.length; i++) {
                 sb.append(hexString.charAt((bytes[i] & 0xf0) >> 4));
                 sb.append(hexString.charAt((bytes[i] & 0x0f) >> 0));
             }
             return sb.toString();
         } catch (Exception e) {
             // TODO Auto-generated catch block
//             e.printStackTrace();
             LogManager.e(Constant.TAG, "encode: ", e);

         }
         return null;
    }
    public static byte[] decodToBytes(String bytes) {
  	  ByteArrayOutputStream baos = null;
      try {
          baos = new ByteArrayOutputStream(bytes.length() / 2);
          for (int i = 0; i < bytes.length(); i += 2)
              baos.write((hexString.indexOf(bytes.charAt(i)) << 4 | hexString
                      .indexOf(bytes.charAt(i + 1))));
           return baos.toByteArray();
      } catch (Throwable e) {
          LogManager.e(Constant.TAG, "encode: ", e);

          } finally {
              if (baos != null) {
                  try {
                      baos.close();
                  } catch (IOException e) {
//                      e.printStackTrace();
                      LogManager.e(Constant.TAG, "encode: ", e);

                  }
              }
          }
          return null;
    }
    public static String decode(String bytes) {
        try {
        	byte[] bt =decodToBytes(bytes);
            return new String(bt, CHARSETNAME);
        } catch (Throwable e) {
//            e.printStackTrace();// TODO: handle Exception
            LogManager.e(Constant.TAG, "encode: ", e);
        }
        return null;
    }
	/* SDK-493 hewngao 20160618 end */
    
    public static byte[] MD5(byte[] input) {
        MessageDigest md = null;
        try {
            md = MessageDigest.getInstance("MD5");
        } catch (NoSuchAlgorithmException e) {
//            e.printStackTrace();
            LogManager.e(Constant.TAG, "MD5: ", e);

        }
        if (md != null) {
            md.update(input);
            return md.digest();
        } else
            return null;
    }

    public static String bytesToHexString(byte[] bytes) {
        if (bytes == null)
            return null;
        String table = "0123456789abcdef";
        int len = 2 * bytes.length;
        char[] cchars = new char[len];// 不再使用StringBuilder,使用char数组优化速度，dmtrace
                                      // 发现string.append最耗时
        for (int i = 0, k = 0; i < bytes.length; i++, k++) {
            int b;
            b = 0x0f & (bytes[i] >> 4);
            cchars[k] = table.charAt(b);
            b = 0x0f & bytes[i];
            k++;
            cchars[k] = table.charAt(b);
        }
        String sret = String.valueOf(cchars);
        cchars = null;
        return sret;
    }

    public static String getMD5(byte[] input) {
        return bytesToHexString(MD5(input));
    }

    public static String getMD5(String input) {
        return getMD5(input.getBytes());
    }

    public static String getFileMD5(String filePath) {
		InputStream fis = null;
		int numRead = 0;
		MessageDigest md5;
		try {
			fis = new FileInputStream(filePath);
			if (fis != null) {
				byte[] buffer = new byte[1024];
				md5 = MessageDigest.getInstance("MD5");
				while ((numRead = fis.read(buffer)) > 0) {
					md5.update(buffer, 0, numRead);
				}
				fis.close();
				return getMD5(md5.digest());
			}
		}
		catch (Throwable e) {

		}
		return null;
    }

    public static Document stringConvertXML(String data, String code) {
        if (StringUtils.isNull(data)) {
            return null;
        }
        Document doc = null;
        InputStream is = null;
        try {
            if (data.indexOf("?>") != -1) {
                data = data.substring(data.indexOf("?>") + 2);
            }
            StringBuilder sXML = new StringBuilder(code);
            sXML.append(data);
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            is = new ByteArrayInputStream(sXML.toString().getBytes("utf-8"));
            doc = dbf.newDocumentBuilder().parse(is);
        } catch (Throwable e) {
            LogManager.e(Constant.TAG, "stringConvertXML error ", e);
        } finally {
            FileUtils.close(is);
        }
        return doc;
    }

    public static String getValueByKey(Map<String, String> extend, String key) {
        if (extend != null && !extend.isEmpty() && !StringUtils.isNull(key)) {
            return extend.get(key);
        }
        return "";
    }

    /**
     * 将Json数组转换成list
     * 
     * @param arr
     * @return
     */
    public static List<String> arryToList(JSONArray arr) {
        try {
            if (arr != null && arr.length() > 0) {
                List<String> list = new ArrayList<String>();
                for (int i = 0; i < arr.length(); i++) {
                    list.add(arr.get(i).toString());
                }
                return list;
            }
        } catch (JSONException e) {
            // TODO Auto-generated catch block
//            e.printStackTrace();
            LogManager.e(Constant.TAG, "arryToList: ", e);

        }
        return null;
    }

    /**
     * 将json数组转换成普通的数组
     * 
     * @param arr
     * @return
     */
    public static String[] jsonArryToArray(JSONArray arr) {
        if (arr != null && arr.length() > 0) {
            String[] str = new String[arr.length()];
            for (int i = 0; i < arr.length(); i++) {
                try {
                    str[i] = arr.getString(i);
                } catch (JSONException e) {
//                    e.printStackTrace();
                    LogManager.e(Constant.TAG, "jsonArryToArray: ", e);

                }
            }
            return str;
        }
        return null;
    }

    /**
     * 得到非空字符串
     * 
     * @param str
     * @return
     */
    public static String getNoNullString(String str) {
        if (str == null) {
            return "";
        }
        return str.trim();
    }

    public static long getLongByString(String longStr) {
        try {
            if (!StringUtils.isNull(longStr)) {
                return Long.parseLong(longStr);
            }
        } catch (Throwable e) {
//            e.printStackTrace();
            LogManager.e(Constant.TAG, "getLongByString: ", e);

            return -1;
        }
        return -1;

    }

    // 获取两位长度的动作类型
    public static String getTwoDigitType(String type) {
        if (StringUtils.isNull(type)) {
            return "";
        }
        if (type.length() < 2) {
            return "0" + type;
        } else if (type.length() > 2) {
            return "99";
        }
        return type;
    }

    public static String replaceBlank(String oldStr) {
        if (StringUtils.isNull(oldStr))
            return null;
        // return oldStr.replaceAll("\\s*", "");//性能慢
        return oldStr.replaceAll("\\s", "");
    }

    /* SDK-570 huangzhiqiang 20160802 start */
    public static String handlerAssemble(String arg) {
        try {
            StringBuffer sb = new StringBuffer();
            for (int i = 0; i < 4; i++) {
                int index = i * 16;
                sb.append(decode(arg.substring(index, index + 16)));
            }
            return sb.toString();
        } catch (Throwable e) {
            LogManager.e(Constant.TAG, "StringUtils handlerAssemble error", e);
        }
        return "";
    }
    /* SDK-570 huangzhiqiang 20160802 end */

    /* SDK-397 huangzhiqiang 20160524 start */
    /**
     * 字符串数组内的所有字符串不为空或null
     * 
     * @param values
     * @return true:所有值不为空或null  false:有值为空或null
     */
    public static boolean allValuesIsNotNull(String... values) {
        if (values == null || values.length == 0) {
            return false;
        }
        for (String value : values) {
            if (StringUtils.isNull(value)) {
                return false;
            }
        }
        return true;
    }
    /* SDK-397 huangzhiqiang 20160524 end */

    /* SDK-569 huangzhiqiang 20160728 start */
    /**
     * 去除字符串内的空格、回车、tab
     * 
     * @param value
     * @return 返回去除空格、回车、tab后的字符串，如果字符串为null时会返回"";
     */
    public static String trim(String value) {
        if (value == null || value.length() == 0) {
            return "";
        }
        return value.trim().replace("\r", "").replace("\n", "").replace("\t", "");
    }
    /* SDK-569 huangzhiqiang 20160728 end */
}
